from __future__ import with_statement
"""
Created on 18-Dec-2009

@author: dexen
"""

import time
import threading 
from dexen.system.common.states import M_RUNNING, M_FINISHED


# TODO: ensure the release of locks during failure.
class MasterComm(object):    
    def __init__(self, name):
        self.lock = threading.Lock()
        self.actions = []
        self.slave_name = None
        self.state = M_RUNNING
        self.num_slaves_can_schedule = 0
        self.slave_names = []
        self.slaves_pending = False
    
    def is_slaves_pending(self):
        with self.lock:
            return self.slaves_pending
    
    def set_num_slaves_can_schedule(self, val):
        with self.lock:
            self.num_slaves_can_schedule = val
    
    def num_slaves_needed(self):
        with self.lock:
            return self.num_slaves_can_schedule
    
    def can_schedule(self):
        with self.lock:
            return self.slave_name == None
                  
    def assign_slave(self, slave_name):
        with self.lock:
            self.slave_name = slave_name
    
    def assign_slaves(self, slave_names):
        with self.lock:
            self.slave_names.extend(slave_names)
            self.num_slaves_can_schedule = self.num_slaves_can_schedule - len(slave_names)
            self.slaves_pending = True
    
    def get_slaves(self):
        with self.lock:
            res = self.slave_names
            self.slave_names = []
            self.slaves_pending = False
            return res
    
    def has_slave(self):
        with self.lock:
            return self.slave_name != None
    
    def get_slave(self):
        with self.lock:
            slave_name = self.slave_name
            self.slave_name = None
            return slave_name
         
    def get_actions(self):
        with self.lock:
            actions = self.actions
            self.actions = []
            return actions

    def add_action(self, action):
        with self.lock:
            self.actions.append(action)

    def is_running(self):
        with self.lock:
            return self.state == M_RUNNING

    def has_stopped(self):
        with self.lock:
            return self.state == M_FINISHED

    def stop(self):
        with self.lock:
            self.state = M_FINISHED
    
    